package cn.autumnorange.commons.util;

import org.apache.commons.lang3.time.DateUtils;
import org.springframework.util.StringUtils;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * 日期转换工具类 时间转换工具类
 *
 * @author eiven
 */
public final class DateConverUtil extends DateUtils {
  /**
   * 参数设定或系统特定格式的字符串 转换成 日期时间格式
   *
   * @param sdate 传入的字符串。例如：2017-11-05
   * @param toTypes 传入的字符串时间类型格式，例如：yyyy-MM-dd HH:mm:ss
   * @return Date日期对象
   *     <p>示例：String time="2013-11-01 11:22";
   *     DateConverUtil.getDatebyStr(time);或者DateConverUtil.getDatebyStr(time,"yyyy-MM-dd HH:mm");
   */
  public static Date getDatebyStr(String sdate, String... toTypes) {
    Date date = null;
    if (StringUtils.hasText(sdate)) {
      boolean a = true;
      if (a) {
        for (String toType : toTypes) {
          try {
            date = getDateFormat(toType).parse(sdate);
            a = false;
            break;
          } catch (Exception e) {
            continue;
          }
        }
      }
      if (a) {
        for (TimeType toType : TimeType.values()) {
          try {
            date = getDateFormat(toType.getValue()).parse(sdate);
            a = false;
            break;
          } catch (Exception e) {
            continue;
          }
        }
      }
    }
    return date;
  }

  public static int currentTimeStamp() {
    return Integer.parseInt(String.valueOf(System.currentTimeMillis() / 1000));
  }

  /**
   * 日期时间格式 转换成 参数设定或系统特定格式的字符串
   *
   * @param type 传入的转换成的日期格式 , DateConverUtil.TimeType中有一部分日期时间格式
   * @return 字符串类型
   *     <p>示例：DateConverUtil.dd2(new Date(),DateConverUtil.TimeType.type2.getValue()) 或者
   *     DateConverUtil.dd2(new Date(),"yyyy-MM-dd H:m:s") ;
   */
  public static String getStrbyDate(Date date, String type) {
    try {
      return getDateFormat(type).format(date);
    } catch (Exception e) {
      return null;
    }
  }

  /**
   * 参数设定或系统特定格式的日期时间字符串 转换成 参数设定字符串格式的日期时间
   *
   * @param sdate 传入的日期字符串
   * @param targetType 传入的转换后的参数设定日期时间 格式
   * @param sourceType 传入的转换前的日期时间 格式
   * @return 字符串类型
   *     <p>示例：DateConverUtil.dd3("2015-2-11","yyyy年MM月dd日","yyyy-M-dd") ;
   */
  public static String getSbySST(String sdate, String targetType, String... sourceType) {
    try {
      return getStrbyDate(getDatebyStr(sdate, sourceType), targetType);
    } catch (Exception e) {
      return null;
    }
  }

  /**
   * 获取当前系统时间
   *
   * @return
   */
  public static Date getNowTime() {
    Calendar calendar = Calendar.getInstance();
    return calendar.getTime();
  }

  /**
   * 用指定的年、月、日构造日期对象
   *
   * @param year 年
   * @param month 月
   * @param day 日
   * @return 日期对象
   */
  public static Date getTimeByYMD(int year, int month, int day) {
    Calendar calendar = Calendar.getInstance();
    calendar.set(year, month - 1, day);
    return calendar.getTime();
  }

  /**
   * 设为严格格式
   *
   * @param type 传入的格式
   * @return SimpleDateFormat的对象
   */
  public static DateFormat getDateFormat(String type) {
    DateFormat dateFormat = new SimpleDateFormat(type);
    dateFormat.setLenient(false);
    return dateFormat;
  }

  /**
   * 计算时间
   *
   * @param date 日期
   * @param field 类型 如按秒计算为： Calendar.SECOND
   * @param amount 计算量
   * @return
   * @throws Exception 例子：计算当前时间的前10秒的时间？ TimeCalculate(new Date(), Calendar.SECOND, -10)
   *     例子：计算当前时间的后10秒的时间？ TimeCalculate(new Date(), Calendar.SECOND, 10)
   */
  public static Date TimeCalculate(Date date, int field, int amount) {
    try {
      Calendar cal = Calendar.getInstance();
      cal.setTime(date);
      cal.add(field, amount);
      return cal.getTime();
    } catch (Exception e) {
      return null;
    }
  }

  /** 取得当月天数 */
  public static int getCurrentMonthLastDay() {
    Calendar a = Calendar.getInstance();
    // 把日期设置为当月第一天
    a.set(Calendar.DATE, 1);
    // 日期回滚一天，也就是最后一天
    a.roll(Calendar.DATE, -1);
    int maxDate = a.get(Calendar.DATE);
    return maxDate;
  }

  /** 得到指定月的天数 */
  public static int getMonthLastDay(int year, int month) {
    Calendar a = Calendar.getInstance();
    a.set(Calendar.YEAR, year);
    a.set(Calendar.MONTH, month - 1);
    // 把日期设置为当月第一天
    a.set(Calendar.DATE, 1);
    // 日期回滚一天，也就是最后一天
    a.roll(Calendar.DATE, -1);
    int maxDate = a.get(Calendar.DATE);
    return maxDate;
  }

  /** 获取今天是几号 */
  public static int getDay() {
    Calendar c = Calendar.getInstance();
    int today = c.get(Calendar.DAY_OF_MONTH);
    return today;
  }

  /** 获取当日开始时间 */
  public static Date getStartTime() {
    Calendar todayStart = Calendar.getInstance();
    todayStart.set(Calendar.HOUR_OF_DAY, 0);
    todayStart.set(Calendar.MINUTE, 0);
    todayStart.set(Calendar.SECOND, 0);
    todayStart.set(Calendar.MILLISECOND, 0);
    return todayStart.getTime();
  }
  /** 当前该系统提供的一些日期时间格式——————使用的是枚举 */
  public enum TimeType {
    /** "yyyy-MM-dd HH:mm:ss" */
    type1("yyyy-MM-dd HH:mm:ss"),
    /** "yyyy/MM/dd HH:mm:ss" */
    type2("yyyy/MM/dd HH:mm:ss"),
    /** "yyyy.MM.dd HH:mm:ss" */
    type3("yyyy.MM.dd HH:mm:ss"),
    /** "yyMMdd HH:mm:ss" */
    type4("yyyyMMdd HH:mm:ss"),
    /** "yyyy年MM月dd日 HH:mm:ss" */
    type5("yyyy年MM月dd日 HH:mm:ss"),

    /** "yyyy-MM-dd HH:mm" */
    type11("yyyy-MM-dd HH:mm"),
    /** "yyyy/MM/dd HH:mm" */
    type21("yyyy/MM/dd HH:mm"),
    /** "yyyy.MM.dd HH:mm" */
    type31("yyyy.MM.dd HH:mm"),
    /** "yyMMdd HH:mm" */
    type41("yyyyMMdd HH:mm"),
    /** "yyyy年MM月dd日 HH:mm" */
    type51("yyyy年MM月dd日 HH:mm"),

    /** "yyyy-MM-dd" */
    type111("yyyy-MM-dd"),
    /** "yyyy/MM/dd" */
    type211("yyyy/MM/dd"),
    /** "yyyy.MM.dd" */
    type311("yyyy.MM.dd"),
    /** "yyMMdd" */
    type411("yyyyMMdd"),
    /** "yyyy年MM月dd日" */
    type511("yyyy年MM月dd日"),

    /** "yyyy-MM-dd" */
    type1111("yyyy-MM"),
    /** "yyyy/MM/dd" */
    type2111("yyyy/MM"),
    /** "yyyy.MM.dd" */
    type3111("yyyy.MM"),
    /** "yyMMdd" */
    type4111("yyyyMM"),
    /** "yyyy年MM月dd日" */
    type5111("yyyy年MM月"),

    /** "yyyy-MM-dd" */
    type11111("yyyy"),
    /** "HH:mm:ss" */
    type6("HH:mm:ss");

    private final String value;

    TimeType(String value) {
      this.value = value;
    }

    public String getValue() {
      return value;
    }
  }
}
